﻿package 
{
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.system.ApplicationDomain;
	
	/**
	 * ...
	 * @author kot
	 * 
	 */
	
	public class Figure extends MovieClip {
		public const WHITE : int = 2;
		public const BLACK : int = 1;
		public var figureX : int;
		public var figureY : int;
		protected var figureColor : int; // 0 - empty, 1 - black, 2 - white
		public var moves : Array = new Array();
		
		public function Figure() {
			addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		}
		
		///////////////////////////////////
		//if figure can move, start dragging
		////////////////////////////////////
		public function onMouseDown(evt : MouseEvent) {
			
			if (figureColor != Board(parent).getMove()) { //
				return;
			}
			if (moves.length == 0) {
				return;
			}
			Board(parent).resetCells();
			parent.setChildIndex(this, parent.numChildren - 1);
			for (var i = 0; i < moves.length; i++) {
				Board(parent).getCell(moves[i].x, moves[i].y).setAvaliable(true);
			}
			startDrag(true);
		}
		
		public function onMouseUp(evt : MouseEvent) {
			
			//check, if available
			stopDrag();			
			if (dropTarget == null || dropTarget.parent == null) {
				Board(parent).resetCells();
				Board(parent).getCell(figureX, figureY).resetFigure(this);
				trace("wrong destination");
				return;
			}
			var cellToMove : Cell;		
			var PawnedFigure : Figure = null;
			if (dropTarget.parent is Cell) {
				cellToMove = dropTarget.parent as Cell;
			} else {
				PawnedFigure = dropTarget.parent as Figure;
				cellToMove = Board(parent).getCell(PawnedFigure.figureX, PawnedFigure.figureY);
			} 
			if (!cellToMove.isAvailable) {
				Board(parent).resetCells();
				Board(parent).getCell(figureX, figureY).resetFigure(this);
				trace("wrong destination");
				return;
			}
			
			Board(parent).resetCells();
			
			//check for king and pawn
			if (this.toString() == "King") {
				(this as King).updateKing(cellToMove.nameX, cellToMove.nameY);
			}
			if (this.toString() == "Rook") {
				(this as Rook).setMoved();
			}
			
			PawnedFigure = cellToMove.getFigure();
			Board(parent).getCell(figureX, figureY).removeFigure();
			if (PawnedFigure != null) {
				Board(parent).removeChild(PawnedFigure);
				cellToMove.removeFigure();
			}
			cellToMove.addFigure(this);
			if (this.toString() == "Pawn") {
				(this as Pawn).updatePawn(cellToMove);
			}
			
			//TODO send figure move
			Board(parent).changeMove();
		}
		
		public function insideBoard(x : int, y : int): Boolean {
			return (x >= 0 && x < 8 && y >= 0 && y < 8);
		}
		
		/// returns if cell is empty of occupied by enemy figure
		public function checkCell(x:int, y : int) : Boolean {
			if (!insideBoard(x, y))
				return false;
			if ((Board(parent)).getCell(x, y).isEmpty()) {
				return true;
			}
			return ((Board(parent)).getCell(x, y).getFigure().getFigureColor() != figureColor);
		}
		
		override public function toString() : String {
			return "Figure";
		}
		
		/** Wave function adds available moves 
		* @xx, @yy - change of direction of wave
		* needed for Queen, Rook, Bishop
		*/
		public function waveMove(xx : int, yy : int) : void {
			var x = figureX + xx;
			var y = figureY + yy;
			while (checkCell(x, y)) {
				moves.push(new Point(x, y));
				if (Board(parent).getCell(x, y).isEmpty()){
					x += xx;
					y += yy;
				} else
					break;
			}
		}
		/// reset all previous moves
		public function resetMoves() : void {
			moves = new Array();
		}
		/// abstract function 
		/// returns if Figure may reach x,y point
		public function canMove(x : int, y : int) : Boolean {
			return false;
		}
		
		/// returns figure color
		public function getFigureColor() : int {
			return figureColor;
		}
		
		/// sets figure color
		public function setFigureColor(color : int) : void {
			this.figureColor = color;
		}
		
		/// abstract function 
		/// gets all available moves of figure
		public function getAvailableMoves() : int {
			return 0;
		}
	}

}